package com.alks.function.service.impl.pcfactoryquery;

import com.alks.common.aop.AutoPageAop;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.utils.beanutils.ArrayUtils;
import com.alks.common.utils.beanutils.BeanUtil;
import com.alks.entity.data.entity.PcCuttingLsHead;
import com.alks.entity.data.entity.PcCuttingLsPart;
import com.alks.entity.data.entity.PcLotHead;
import com.alks.entity.data.enums.factoryquery.PcProcessEnum;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.function.data.dto.pcfactoryquery.PcCuttingPartDto;
import com.alks.function.data.dto.pcfactoryquery.PcCuttingPartLotDto;
import com.alks.function.data.dto.pcfactoryquery.PcCuttingPartSpDto;
import com.alks.function.data.request.factoryquery.CuttingPartRequest;
import com.alks.function.data.request.factoryquery.CuttingPartSpRequest;
import com.alks.function.data.request.factoryquery.LotStyleRerquest;
import com.alks.function.mapper.biocontrol.webwork.PcCuttingLsHeadMapper;
import com.alks.function.mapper.chengKong.PcLotHeadMapper;
import com.alks.function.mapper.pcfactoryquery.FT_QR_PcCuttingDailyProdSizeMapper;
import com.alks.function.mapper.pcfactoryquery.FT_QR_PcCuttingLsPartMapper;
import com.alks.function.service.pcfactoryquery.IPcCuttingLsPartService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * <p>
 * 冲裁出入库表 服务实现类
 * </p>
 *
 * @author ms
 * @since 2023-08-07
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class PcCuttingLsPartServiceImpl extends ServiceImpl<FT_QR_PcCuttingLsPartMapper, PcCuttingLsPart> implements IPcCuttingLsPartService {
    private final FT_QR_PcCuttingLsPartMapper cutMapper;
    private final PcLotHeadMapper lotHeadMapper;
    private final PcCuttingLsHeadMapper lsHeadMapper;
    private final FT_QR_PcCuttingDailyProdSizeMapper sizeMapper;

    @Override
    public ResponseInfo queryCuttingPartLsDetail(CuttingPartRequest request) {
        int stkCode = 3;
        String companyId = UserIdThread.get().getCompanyId();
        /*入参判断*/
        if (!PcProcessEnum.isProcessCodeExist(request.getProcessCode())) {
            return ResponseInfo.error("工艺类型输入异常");
        }
        if (!request.getMtlCode().equals(1) && !request.getMtlCode().equals(2) && !request.getMtlCode().equals(3)) {
            return ResponseInfo.error("查询数据不合规");
        }
        /*获取基础数据*/
        List<PcCuttingPartDto> dtos = cutMapper.queryCuttingPartDetail(request, companyId);
        /*无派工数据情况就没有收发数据*/
        if (ArrayUtils.isEmpyt(dtos)) {
            log.warn("\n异常接口：queryCuttingPartLsDetail\n异常原因:无派工数据\n" +
                            "查询条件：LOT_NO = {}，LS_NO = {}，PROCESS_CODE = {}",
                    request.getLotNo(), request.getProcessCode(), request.getLsNo());
            return ResponseInfo.ok();
        }
        /*获取收发数量和号码数据*/
        List<Map<String, Object>> partSizes = cutMapper.accountSizeQtyQuery(request, companyId);
        Map<String, Map<String, String>> partSizeMap = new HashMap<>();
        for (Map<String, Object> partSize : partSizes) {
            String partName = partSize.get("partName").toString();
            Map<String, String> sizeMap = partSizeMap.get(partName)==null?new HashMap<>():partSizeMap.get(partName);
            sizeMap.put(partSize.get("sizeNo").toString(), partSize.get("qty").toString());
            partSizeMap.put(partName, sizeMap);
        }
        /*获取求和数据*/
        List<String> partNames = dtos.stream().map(PcCuttingPartDto::getPartName).collect(Collectors.toList());
        ArrayList<String> sizeNos = partSizes.stream().map(a -> a.get("sizeNo").toString()).distinct().collect(Collectors.toCollection(ArrayList::new));
        BigDecimal totalSum;
        Map<String, String> sumMap = new HashMap<>();
        Map<String, BigDecimal> supportTotalMap = new HashMap<>();
        if (request.getMtlCode().equals(stkCode)) {
            /*获取合计*/
            Map<String, BigDecimal> partQtyMap = partSizes.stream()
                    .collect(Collectors.toMap(a -> a.get("partName").toString(),
                            a -> (BigDecimal) a.get("qty"), BigDecimal::add));
            for (String partName : partNames) {
                sumMap.put(partName, partQtyMap.get(partName).toString());
            }
            /*获取配套*/
            Map<String, Integer> sizeQtyMap = partSizes.stream()
                    .collect(Collectors.toMap(a -> a.get("sizeNo").toString(),
                            a -> (Integer) a.get("qty"), Math::min));
            for (String sizeNo : sizeNos) {
                BigDecimal qty = BigDecimal.valueOf(sizeQtyMap.get(sizeNo));
                supportTotalMap.put(sizeNo, qty);
                getSumMap(supportTotalMap, "total", qty);
            }
        } else {
            /*size为配套 part为合计*/
            Map<String, Integer> sizeQtyMap = new HashMap<>();
            Map<String, BigDecimal> partQtyMap1 = new HashMap<>();
            Map<String, BigDecimal> partQtyMap2 = new HashMap<>();
            for (Map<String, Object> partSize : partSizes) {
                String qty = partSize.get("qty").toString();
                String[] split = qty.split("/");
                int qty1 = Integer.parseInt(split[0]);
                int qty2 = Integer.parseInt(split[1]);
                String sizeNo = partSize.get("sizeNo").toString();
                String partName = partSize.get("partName").toString();
                sizeQtyMap.put(sizeNo, sizeQtyMap.get(sizeNo) == null ? qty2 : Math.min(sizeQtyMap.get(sizeNo), qty2));
                getSumMap(partQtyMap1, partName, BigDecimal.valueOf(qty1));
                getSumMap(partQtyMap2, partName, BigDecimal.valueOf(qty2));
            }
            for (String partName : partNames) {
                sumMap.put(partName, partQtyMap1.get(partName) + "/" + partQtyMap2.get(partName));
            }
            for (String sizeNo : sizeNos) {
                BigDecimal qty = BigDecimal.valueOf(sizeQtyMap.get(sizeNo));
                supportTotalMap.put(sizeNo, qty);
                getSumMap(supportTotalMap, "total", qty);
            }
        }
        /*补充数量号码数据*/
        for (PcCuttingPartDto dto : dtos) {
            Map<String, String> sizeQty = partSizeMap.get(dto.getPartName());
            dto.setQty(sizeQty);
        }
        /*数据操作和封装*/
        Map<String, Object> map = new HashMap<>(2);
        /*封装输出结果*/
        map.put("supportTotal", supportTotalMap);
        map.put("dto", dtos);
        return ResponseInfo.ok(map);
    }

    private void getSumMap(Map<String, BigDecimal> map, String key, BigDecimal value) {
        map.put(key, map.get(key) == null ? value : map.get(key).add(value));
    }

    @Override
    @AutoPageAop
    public ResponseInfo queryCuttingPartLsLot(LotStyleRerquest request) {
        String companyId = UserIdThread.get().getCompanyId();
        /*获取数据*/
        List<PcLotHead> lotHeads = lotHeadMapper.pcVCutQueryLot(request,companyId);
        Stream<String> lotNos = lotHeads.stream().map(PcLotHead::getLotNo);
        Page<PcLotHead> page = (Page<PcLotHead>) lotHeads;
        /*拷贝提取*/
        Map<String, Object> map = new HashMap<>(2);
        map.put("total", page.getTotal());
        map.put("dto", lotNos);
        return ResponseInfo.ok(map);
    }

    @Override
    public Map<String, Object> queryCuttingPartLs(String lotNo) {
        String companyId = UserIdThread.get().getCompanyId();
        Map<String, Object> map = new HashMap<>(2);
        /*获取指令明细数据*/
        LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<PcLotHead>()
                .select(PcLotHead::getStyle, PcLotHead::getColor, PcLotHead::getOrderQty)
                .eq(PcLotHead::getLotNo, lotNo)
                .eq(PcLotHead::getCompanyId, companyId)
                .groupBy(PcLotHead::getLotNo)
                .orderByDesc(PcLotHead::getSysDate,PcLotHead::getLotNo);
        PcLotHead lotHeads = lotHeadMapper.selectOne(wrapper);
        PcCuttingPartLotDto detail = BeanUtil.copyBean(lotHeads, PcCuttingPartLotDto.class);
        map.put("detail", detail);
        /*获取轮次*/
         LambdaQueryWrapper<PcCuttingLsHead> headWrapper = new LambdaQueryWrapper<PcCuttingLsHead>()
                .select(PcCuttingLsHead::getLsNo)
                .eq(PcCuttingLsHead::getLotNo, lotNo)
                .last("GROUP BY LS_NO");
        List<PcCuttingLsHead> heads = lsHeadMapper.selectList(headWrapper);
        if (ArrayUtils.isEmpyt(heads)){
            map.put("lsNo", null);
        }else {
            List<Integer> lsNo = heads.stream().map(PcCuttingLsHead::getLsNo).collect(Collectors.toList());
            /*封装返回*/
            map.put("lsNo", lsNo);
        }
        return map;
    }


    @Override
    @AutoPageAop
    public ResponseInfo queryCuttingPartSpHead(CuttingPartSpRequest request) {
        String companyId = UserIdThread.get().getCompanyId();
        /*数据查询*/
        List<PcCuttingPartSpDto> dtos = cutMapper.queryCuttingPartSpHead(request,companyId);
        Page<PcCuttingPartSpDto> page = (Page<PcCuttingPartSpDto>) dtos;
        /*封装返回*/
        Map<String,Object> map = new HashMap(2);
        map.put("total", page.getTotal());
        map.put("dtos", dtos);
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo queryCuttingPartSpDetail(String lotNo) {
        String companyId = UserIdThread.get().getCompanyId();
        /*数据查询*/
        List<PcCuttingPartSpDto> dtos = cutMapper.queryCuttingPartSpDetail(lotNo,companyId);
        return ResponseInfo.ok(dtos);
    }

    @Override
    public ResponseInfo queryCuttingPartBack() {
        return ResponseInfo.ok(PcProcessEnum.toMap());
    }

    @Override
    public ResponseInfo queryCuttingGropByPart(String lotNo, String processCode, String sizeNo, Integer spFlag) {
        String companyId = UserIdThread.get().getCompanyId();
        /*制程转换*/
        processCode= PcProcessEnum.getCodeByName(processCode);
        /*数据查询*/
        List<PcCuttingPartSpDto> dtos = cutMapper.queryCuttingGropByPart(lotNo,processCode, sizeNo,spFlag,companyId);
        return ResponseInfo.ok(dtos);
    }
}
